# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from google.appengine.ext import db

class Player(db.Model):
    container = db.StringProperty(required=True)
    userId = db.StringProperty(required=True)
    name = db.StringProperty(required=True)
    photoUrl = db.StringProperty()

    price = db.IntegerProperty()
    cash = db.IntegerProperty()
    capital = db.IntegerProperty()
    slavenum = db.IntegerProperty(default=0)

    masterid = db.StringProperty()
    mastername = db.StringProperty()
    
    nickname = db.StringProperty()
    
    def setMaster(self,player):
      self.masterid = player.userId
      self.mastername = player.name
      
    def free(self):
      self.masterid = None
      self.mastername = None
      self.nickname = None

class Activity(db.Model):
    container = db.StringProperty()
    actor = db.StringProperty()
    actorName = db.StringProperty()
    
    target = db.StringProperty()
    targetName = db.StringProperty()
    
    command = db.StringProperty()
    
    time = db.DateTimeProperty(auto_now_add=True)
    until = db.DateTimeProperty(auto_now_add=True)
    
    type = db.IntegerProperty()
    
    arg1 = db.StringProperty()
    arg2 = db.StringProperty()
    arg3 = db.StringProperty()
    arg4 = db.StringProperty()
    arg5 = db.StringProperty()
    
    def setActor(self,player):
      self.actor = player.userId
      self.actorName = player.name
      
    def setTarget(self,player):
      self.target = player.userId
      self.targetName = player.name

class ActivityType:
    (FIX, REWARD, FAWN, BUY) = range(0,4)

class Persist:
    """seperate the persistence layer
    """
    @staticmethod
    def save(model):
      model.put()
    
    @staticmethod
    def loadPlayer(container,uid):
      result = db.GqlQuery("SELECT * FROM Player "\
                           "WHERE container = :1 AND userId = :2",container,uid)
      return result.get()
    
    @staticmethod
    def loadActivity(player):
      """ use two queries for gql not support OR
      """
      actorResult = db.GqlQuery("SELECT * FROM Activity " \
                           "WHERE container = :1 AND " \
                           "actor = :2 order by time desc",player.container,player.userId)
      targetResult = db.GqlQuery("SELECT * FROM Activity " \
                           "WHERE container = :1 AND " \
                           "target = :2 order by time desc",player.container,player.userId)
      
      result = []
      result.extend(actorResult.fetch(10))
      result.extend(targetResult.fetch(10))
      
      timesort = lambda a,b:cmp(a.time,b.time)
      result.sort(cmp=timesort,reverse=True)
      return result[:10]
    
    @staticmethod
    def getLastActivity(actor,target,type):
      if (not actor) and (not target):
        return None
      
      #gql = "SELECT * FROM Activity WHERE type = :1"
      #query = db.GqlQuery(gql,type)
      query = Activity.all()
      query.filter("type =",type)
      
      if actor:
        query.filter("actor =",actor.userId)
        query.filter("container =",actor.container)
      
      if target:
        query.filter("target =",target.userId)
        query.filter("container =",target.container)
        
      query.order("-time")
        
      return query.get()
      
    @staticmethod  
    def loadSlave(player):
      result = db.GqlQuery("SELECT * FROM Player " \
                            "WHERE container = :1 AND masterid = :2",player.container,player.userId)
      return result.fetch(10)
    
    @staticmethod
    def loadFriends(container,ids):
      result = db.GqlQuery("SELECT * FROM Player " \
                            "WHERE container = :1 AND userId IN :2",container,ids)
      return result.fetch(1000)
